<script>
import { difference } from 'lodash';
import { getCookie, setCookie } from '~/lib/utils/common_utils';
import glFeatureFlagsMixin from '~/vue_shared/mixins/gl_feature_flags_mixin';
import LocalStorageSync from '~/vue_shared/components/local_storage_sync.vue';
import { translateScannerNames } from '~/security_configuration/utils';
import SecurityTrainingPromoBanner from 'ee/security_dashboard/components/project/security_training_promo_banner.vue';
import { DOC_PATH_APPLICATION_SECURITY } from 'ee/security_dashboard/constants';
import VulnerabilityReportTabs from '../shared/vulnerability_report/vulnerability_report_tabs.vue';
import AutoFixUserCallout from '../shared/auto_fix_user_callout.vue';
import ProjectPipelineStatus from '../shared/project_pipeline_status.vue';
import securityScannersQuery from '../../graphql/queries/project_security_scanners.query.graphql';
import ReportNotConfiguredProject from './report_not_configured_project.vue';
import SecurityScannerAlert from './security_scanner_alert.vue';

export default {
  components: {
    ReportNotConfiguredProject,
    LocalStorageSync,
    SecurityScannerAlert,
    AutoFixUserCallout,
    ProjectPipelineStatus,
    VulnerabilityReportTabs,
    SecurityTrainingPromoBanner,
  },
  mixins: [glFeatureFlagsMixin()],
  inject: ['fullPath', 'pipeline', 'sbomPipeline', 'hasVulnerabilities'],
  provide: {
    isProjectVulnerabilityReport: true,
  },
  data() {
    return {
      scannerAlertDismissed: false,
      securityScanners: {},
      shouldShowAutoFixUserCallout:
        this.glFeatures.securityAutoFix && !getCookie(this.$options.autoFixUserCalloutCookieName),
    };
  },
  apollo: {
    securityScanners: {
      query: securityScannersQuery,
      variables() {
        return { fullPath: this.fullPath };
      },
      update({ project = {} }) {
        const { available = [], enabled = [], pipelineRun = [] } = project?.securityScanners || {};

        return {
          available: translateScannerNames(available),
          enabled: translateScannerNames(enabled),
          pipelineRun: translateScannerNames(pipelineRun),
        };
      },
    },
  },
  computed: {
    isReportConfigured() {
      // A report is configured when either a pipeline generated a security report, or when
      // vulnerabilities are added through the new vulnerability page or API. There are 3 cases:
      // 1. No vulnerabilities exist and no pipeline has ever generated a security report. The
      //    report is not configured.
      // 2. Vulnerabilities were added through the new vulnerability page or the API. Whether a
      //    pipeline was run does not matter, the report is configured.
      // 3. A pipeline was run that outputted a security report. Whether vulnerabilities exist does
      //    not matter, the report is configured.
      return Boolean(this.pipeline.id) || this.hasVulnerabilities;
    },
    notEnabledSecurityScanners() {
      const { available = [], enabled = [] } = this.securityScanners;
      return difference(available, enabled);
    },
    noPipelineRunSecurityScanners() {
      const { enabled = [], pipelineRun = [] } = this.securityScanners;
      return difference(enabled, pipelineRun);
    },
    shouldShowPipelineStatus() {
      return this.pipeline.createdAt && this.pipeline.id && this.pipeline.path;
    },
    shouldShowScannersAlert() {
      return (
        !this.scannerAlertDismissed &&
        (this.notEnabledSecurityScanners.length > 0 ||
          this.noPipelineRunSecurityScanners.length > 0)
      );
    },
  },
  methods: {
    closeAutoFixUserCallout() {
      setCookie(this.$options.autoFixUserCalloutCookieName, 'true');
      this.shouldShowAutoFixUserCallout = false;
    },
    dismissScannerAlert() {
      this.scannerAlertDismissed = true;
    },
  },
  autoFixUserCalloutCookieName: 'auto_fix_user_callout_dismissed',
  SCANNER_ALERT_DISMISSED_LOCAL_STORAGE_KEY: 'vulnerability_list_scanner_alert_dismissed',
  DOC_PATH_APPLICATION_SECURITY,
};
</script>

<template>
  <report-not-configured-project v-if="!isReportConfigured" />

  <div v-else>
    <local-storage-sync
      v-model="scannerAlertDismissed"
      :storage-key="$options.SCANNER_ALERT_DISMISSED_LOCAL_STORAGE_KEY"
    />
    <security-scanner-alert
      v-if="shouldShowScannersAlert"
      :not-enabled-scanners="notEnabledSecurityScanners"
      :no-pipeline-run-scanners="noPipelineRunSecurityScanners"
      @dismiss="dismissScannerAlert"
    />

    <auto-fix-user-callout
      v-if="shouldShowAutoFixUserCallout"
      class="gl-mt-5"
      :help-page-path="$options.DOC_PATH_APPLICATION_SECURITY"
      @close="closeAutoFixUserCallout"
    />

    <security-training-promo-banner class="gl-mt-5" />

    <vulnerability-report-tabs>
      <template #header-development>
        <project-pipeline-status
          v-if="shouldShowPipelineStatus"
          :pipeline="pipeline"
          :sbom-pipeline="sbomPipeline"
        />
      </template>
    </vulnerability-report-tabs>
  </div>
</template>
